﻿using System;
using System.Collections.Generic;
using System.Drawing.Drawing2D;
using Assist;
using Autodesk.Revit.DB;
using YJKArchUtils.Utils;
using YJKRevitParapet.Forms;

namespace YJKRevitParapet.Previewer
{
	public class ParapetProfileDrawingKit
	{
		public void DrawProfile(ParapetForm.ParapetData parapetData, ref List<CurveInfo> curvesInfoList, ref List<TextNoteInfo> textNoteInfoList, ref List<FillRegion> fillRegions)
		{
			double num = 140.0;
			double num2 = 300.0;
			double num3 = 240.0;
			double num4 = 200.0;
			double num5 = 150.0;
			double num6 = AssistFunc.feetToMM(parapetData.Height);
			double num7 = AssistFunc.feetToMM(parapetData.Thickness);
			XYZ xyz = XYZ.Zero;
			List<XYZ> list = new List<XYZ>();
			XYZ xyz2 = xyz;
			XYZ xyz3 = xyz + XYZ.BasisY * (num4 + num + num6);
			curvesInfoList.Add(this.NewLine(PenColor.PC_Gray, DashStyle.Solid, 2f, xyz2, xyz3));
			xyz2 = xyz + XYZ.BasisX * num3;
			xyz3 = xyz2 + XYZ.BasisY * num4;
			curvesInfoList.Add(this.NewLine(PenColor.PC_Gray, DashStyle.Solid, 2f, xyz2, xyz3));
			this.DrawCuttingLine(new EdgeInfo(xyz, xyz2, 0.0), PenColor.PC_Black, 1f, ref curvesInfoList, ref list);
			list.Add(xyz3 + XYZ.BasisY * num);
			list.Add(xyz3 + XYZ.BasisY * num - XYZ.BasisX * num3);
			FillRegion item = null;
			if (this.CreateFillRegion(list, PenColor.PC_LightGray, PenColor.PC_Black, false, HatchStyle.ForwardDiagonal, ref item))
			{
				fillRegions.Add(item);
			}
			List<XYZ> list2 = new List<XYZ>();
			list2.Add(xyz3 - XYZ.BasisX * (num3 - num7));
			xyz2 = xyz3;
			xyz3 += XYZ.BasisX * num2;
			curvesInfoList.Add(this.NewLine(PenColor.PC_Gray, DashStyle.Solid, 2f, xyz2, xyz3));
			xyz2 = xyz3 + XYZ.BasisY * num;
			this.DrawCuttingLine(new EdgeInfo(xyz3, xyz2, 0.0), PenColor.PC_Black, 1f, ref curvesInfoList, ref list2);
			xyz3 = xyz2 - XYZ.BasisX * (num3 - num7 + num2);
			curvesInfoList.Add(this.NewLine(PenColor.PC_Gray, DashStyle.Solid, 2f, xyz2, xyz3));
			list2.Add(xyz3);
			FillRegion item2 = null;
			if (this.CreateFillRegion(list2, PenColor.PC_LightGray, PenColor.PC_Black, false, HatchStyle.BackwardDiagonal, ref item2))
			{
				fillRegions.Add(item2);
			}
			List<XYZ> list3 = new List<XYZ>();
			xyz2 = xyz3;
			list3.Add(xyz2);
			xyz3 += XYZ.BasisY * num6;
			list3.Add(xyz3);
			curvesInfoList.Add(this.NewLine(PenColor.PC_Gray, DashStyle.Solid, 2f, xyz2, xyz3));
			EdgeInfo centerCurve = new EdgeInfo(xyz3, xyz2, 0.0);
			TextNoteInfo item3 = default(TextNoteInfo);
			XYZ offset = XYZ.BasisX * num5;
			this.DrawDimensions(centerCurve, "墙高", offset, PenColor.PC_Blue, 1f, ref curvesInfoList, ref item3);
			textNoteInfoList.Add(item3);
			xyz2 = xyz3;
			xyz3 -= XYZ.BasisX * num7;
			list3.Add(xyz3);
			curvesInfoList.Add(this.NewLine(PenColor.PC_Gray, DashStyle.Solid, 2f, xyz2, xyz3));
			list3.Add(xyz3 - XYZ.BasisY * num6);
			FillRegion item4 = null;
			if (this.CreateFillRegion(list3, PenColor.PC_LightBlue, PenColor.PC_Black, false, HatchStyle.DiagonalCross, ref item4))
			{
				fillRegions.Add(item4);
			}
			EdgeInfo centerCurve2 = new EdgeInfo(xyz3, xyz2, 0.0);
			TextNoteInfo item5 = default(TextNoteInfo);
			offset = XYZ.BasisY * num5 / 2.0;
			if (parapetData.HasCoping)
			{
				offset = XYZ.BasisY * num5;
			}
			this.DrawDimensions(centerCurve2, "墙厚", offset, PenColor.PC_Blue, 1f, ref curvesInfoList, ref item5);
			textNoteInfoList.Add(item5);
			if (!parapetData.HasCoping)
			{
				return;
			}
			xyz += XYZ.BasisY * (num4 + num + num6);
			if (parapetData.CopingStyleIndex < 4)
			{
				this.DrawCoping(xyz, num7, parapetData.CopingStyleIndex, ref curvesInfoList, ref fillRegions);
				return;
			}
			this.DrawUserCoping(xyz, num7, parapetData.UserProfileCvs, ref curvesInfoList, ref fillRegions);
		}

		private bool CreateFillRegion(List<XYZ> edgeInfo, PenColor backColor, PenColor foreColor, bool isSolid, HatchStyle hatchStyle, ref FillRegion fillRegion)
		{
			if (edgeInfo.Count < 3)
			{
				return false;
			}
			if (!Geometry.IsEqual(edgeInfo[0], edgeInfo[edgeInfo.Count - 1]))
			{
				edgeInfo.Add(edgeInfo[0]);
			}
			List<EdgeInfo> list = new List<EdgeInfo>();
			for (int i = 0; i < edgeInfo.Count - 1; i++)
			{
				list.Add(new EdgeInfo(edgeInfo[i], edgeInfo[i + 1], 0.0));
			}
			fillRegion = new FillRegion(list, backColor, foreColor, isSolid, hatchStyle);
			return true;
		}

		private void DrawCoping(XYZ ptBase, double parapetThickness, int copingStyleIndex, ref List<CurveInfo> curvesInfos, ref List<FillRegion> fillRegions)
		{
			double num = 100.0;
			double num2 = 80.0;
			double num3 = 60.0;
			List<CurveInfo> list = new List<CurveInfo>();
			if (copingStyleIndex == 0)
			{
				XYZ xyz = ptBase + XYZ.BasisX * parapetThickness;
				list.Add(this.NewLine(PenColor.PC_Gray, DashStyle.Solid, 2f, ptBase, xyz));
				XYZ xyz2 = xyz;
				xyz = xyz2 + XYZ.BasisY * num;
				list.Add(this.NewLine(PenColor.PC_Gray, DashStyle.Solid, 2f, xyz2, xyz));
				xyz2 = xyz;
				xyz = xyz2 - XYZ.BasisX * parapetThickness;
				list.Add(this.NewLine(PenColor.PC_Gray, DashStyle.Solid, 2f, xyz2, xyz));
				xyz2 = xyz;
				list.Add(this.NewLine(PenColor.PC_Gray, DashStyle.Solid, 2f, xyz2, ptBase));
			}
			else if (copingStyleIndex == 1)
			{
				XYZ xyz3 = ptBase - XYZ.BasisX * num3;
				XYZ xyz4 = ptBase + XYZ.BasisX * (parapetThickness + num3);
				list.Add(this.NewLine(PenColor.PC_Gray, DashStyle.Solid, 2f, xyz3, xyz4));
				xyz3 = xyz4;
				xyz4 = xyz3 + XYZ.BasisY * num2;
				list.Add(this.NewLine(PenColor.PC_Gray, DashStyle.Solid, 2f, xyz3, xyz4));
				xyz3 = xyz4;
				xyz4 = ptBase - XYZ.BasisX * num3 + XYZ.BasisY * num;
				list.Add(this.NewLine(PenColor.PC_Gray, DashStyle.Solid, 2f, xyz3, xyz4));
				xyz3 = xyz4;
				xyz4 = ptBase - XYZ.BasisX * num3;
				list.Add(this.NewLine(PenColor.PC_Gray, DashStyle.Solid, 2f, xyz3, xyz4));
			}
			else if (copingStyleIndex == 2)
			{
				XYZ xyz5 = ptBase + XYZ.BasisX * parapetThickness;
				list.Add(this.NewLine(PenColor.PC_Gray, DashStyle.Solid, 2f, ptBase, xyz5));
				XYZ xyz6 = xyz5;
				xyz5 = xyz6 + XYZ.BasisY * num2;
				list.Add(this.NewLine(PenColor.PC_Gray, DashStyle.Solid, 2f, xyz6, xyz5));
				xyz6 = xyz5;
				xyz5 = ptBase + XYZ.BasisY * num;
				list.Add(this.NewLine(PenColor.PC_Gray, DashStyle.Solid, 2f, xyz6, xyz5));
				xyz6 = xyz5;
				list.Add(this.NewLine(PenColor.PC_Gray, DashStyle.Solid, 2f, xyz6, ptBase));
			}
			else
			{
				XYZ xyz7 = ptBase - XYZ.BasisX * num3;
				XYZ xyz8 = ptBase + XYZ.BasisX * parapetThickness;
				list.Add(this.NewLine(PenColor.PC_Gray, DashStyle.Solid, 2f, xyz7, xyz8));
				xyz7 = xyz8;
				xyz8 = xyz7 + XYZ.BasisY * num2;
				list.Add(this.NewLine(PenColor.PC_Gray, DashStyle.Solid, 2f, xyz7, xyz8));
				xyz7 = xyz8;
				xyz8 = ptBase - XYZ.BasisX * num3 + XYZ.BasisY * num;
				list.Add(this.NewLine(PenColor.PC_Gray, DashStyle.Solid, 2f, xyz7, xyz8));
				xyz7 = xyz8;
				xyz8 = ptBase - XYZ.BasisX * num3;
				list.Add(this.NewLine(PenColor.PC_Gray, DashStyle.Solid, 2f, xyz7, xyz8));
			}
			curvesInfos.AddRange(list);
			List<XYZ> list2 = new List<XYZ>();
			foreach (CurveInfo curveInfo in list)
			{
				list2.Add(curveInfo.CurveObj.GetEndPoint(0));
			}
			FillRegion item = null;
			if (this.CreateFillRegion(list2, PenColor.PC_LightBlue, PenColor.PC_Black, false, HatchStyle.DiagonalCross, ref item))
			{
				fillRegions.Add(item);
			}
		}

		private void DrawUserCoping(XYZ ptBase, double dParapetThickness, List<Curve> lstCvs, ref List<CurveInfo> curvesInfos, ref List<FillRegion> fillRegions)
		{
			Transform transform = Transform.CreateTranslation(ptBase + XYZ.BasisX * dParapetThickness * 0.5);
			transform = transform.ScaleBasis(304.8);
			List<CurveInfo> list = new List<CurveInfo>();
			foreach (Curve curve in lstCvs)
			{
				Curve curve2 = curve.CreateTransformed(transform);
				list.Add(new CurveInfo(curve2, PenColor.PC_Gray, DashStyle.Solid, 2f));
			}
			curvesInfos.AddRange(list);
			List<XYZ> list2 = new List<XYZ>();
			foreach (CurveInfo curveInfo in list)
			{
				list2.Add(curveInfo.CurveObj.GetEndPoint(0));
			}
			FillRegion item = null;
			if (this.CreateFillRegion(list2, PenColor.PC_LightBlue, PenColor.PC_Black, false, HatchStyle.DiagonalCross, ref item))
			{
				fillRegions.Add(item);
			}
		}

		private void DrawDimensions(EdgeInfo centerCurve, string labelText, XYZ offset, PenColor color, float LineWidth, ref List<CurveInfo> curveInfoList, ref TextNoteInfo textInfo)
		{
			XYZ xyz = centerCurve.StartPoint + offset;
			XYZ xyz2 = centerCurve.EndPoint + offset;
			XYZ xyz3 = Geometry.RotateTo((xyz2 - xyz).Normalize(), Math.PI*.5, XYZ.BasisZ);
			double num = 50.0;
			double num2 = 100.0;
			curveInfoList.Add(this.NewLine(color, DashStyle.Solid, LineWidth, xyz, xyz2));
			XYZ pt = (xyz2 - xyz).Normalize();
			XYZ xyz4 = Geometry.RotateTo(pt, Math.PI*.5, XYZ.BasisZ).Normalize() * num;
			XYZ xyz5 = Geometry.RotateTo(pt, 0.78539816339744828, XYZ.BasisZ).Normalize() * num;
			curveInfoList.Add(this.NewLine(color, DashStyle.Solid, LineWidth, xyz + xyz4, xyz - xyz4));
			curveInfoList.Add(this.NewLine(color, DashStyle.Solid, LineWidth, xyz + xyz5, xyz - xyz5));
			curveInfoList.Add(this.NewLine(color, DashStyle.Solid, LineWidth, xyz2 + xyz4, xyz2 - xyz4));
			curveInfoList.Add(this.NewLine(color, DashStyle.Solid, LineWidth, xyz2 + xyz5, xyz2 - xyz5));
			XYZ xyz6 = Geometry.CalculatMidPoint(xyz, xyz2);
			double num3 = num2 * 1.5;
			XYZ xyz7 = xyz3 * num3;
			xyz6 += xyz7;
			textInfo = new TextNoteInfo(labelText, PenColor.PC_Black, num2, xyz6, num2 * (double)labelText.Length * 2.0, num2 * 2.0);
		}

		private void DrawCuttingLine(EdgeInfo centerCurve, PenColor color, float LineWidth, ref List<CurveInfo> curveInfoList, ref List<XYZ> edgeInfoList)
		{
			XYZ startPoint = centerCurve.StartPoint;
			XYZ endPoint = centerCurve.EndPoint;
			XYZ xyz = (endPoint - startPoint).Normalize();
			XYZ xyz2 = Geometry.RotateTo(xyz, Math.PI*.5, XYZ.BasisZ);
			double num = startPoint.DistanceTo(endPoint) / 10.0;
			XYZ ptS = startPoint - xyz * num * 2.0;
			edgeInfoList.Add(startPoint);
			XYZ xyz3 = startPoint + xyz * num * 3.0;
			edgeInfoList.Add(xyz3);
			XYZ xyz4 = startPoint + xyz * num * 4.0 + xyz2 * num * 2.0;
			edgeInfoList.Add(xyz4);
			XYZ xyz5 = endPoint - xyz * num * 4.0 - xyz2 * num * 2.0;
			edgeInfoList.Add(xyz5);
			XYZ xyz6 = endPoint - xyz * num * 3.0;
			edgeInfoList.Add(xyz6);
			edgeInfoList.Add(endPoint);
			XYZ ptE = endPoint + xyz * num * 2.0;
			curveInfoList.Add(this.NewLine(PenColor.PC_Black, DashStyle.Solid, LineWidth, ptS, startPoint));
			curveInfoList.Add(this.NewLine(PenColor.PC_Black, DashStyle.Solid, LineWidth, startPoint, xyz3));
			curveInfoList.Add(this.NewLine(PenColor.PC_Black, DashStyle.Solid, LineWidth, xyz3, xyz4));
			curveInfoList.Add(this.NewLine(PenColor.PC_Black, DashStyle.Solid, LineWidth, xyz4, xyz5));
			curveInfoList.Add(this.NewLine(PenColor.PC_Black, DashStyle.Solid, LineWidth, xyz5, xyz6));
			curveInfoList.Add(this.NewLine(PenColor.PC_Black, DashStyle.Solid, LineWidth, xyz6, endPoint));
			curveInfoList.Add(this.NewLine(PenColor.PC_Black, DashStyle.Solid, LineWidth, endPoint, ptE));
		}

		private CurveInfo NewArc(PenColor color, DashStyle dashStyle, float lineWidth, XYZ ptS, XYZ ptE, XYZ ptM)
		{
			Arc curve = null;
			CurveInfo result;
			try
			{
				curve = Arc.Create(ptS, ptE, ptM);
				result = new CurveInfo(curve, color, dashStyle, lineWidth);
			}
			catch (Exception)
			{
				result = new CurveInfo(curve, color, dashStyle, lineWidth);
			}
			return result;
		}

		private CurveInfo NewLine(PenColor color, DashStyle dashStyle, float lineWidth, XYZ ptS, XYZ ptE)
		{
			Line curve = null;
			CurveInfo result;
			try
			{
				curve = Line.CreateBound(ptS, ptE);
				result = new CurveInfo(curve, color, dashStyle, lineWidth);
			}
			catch (Exception)
			{
				result = new CurveInfo(curve, color, dashStyle, lineWidth);
			}
			return result;
		}

		protected const PenColor m_CurveColor = PenColor.PC_Gray;

		protected const PenColor m_TextColor = PenColor.PC_Black;

		protected const PenColor m_DimensionColor = PenColor.PC_Black;

		protected const DashStyle m_Solid = DashStyle.Solid;

		protected const DashStyle m_Dash = DashStyle.Dash;

		protected const float m_LineWidth1 = 1f;

		protected const float m_LineWidth2 = 2f;
	}
}
